package com.xxmw.transaction.controller.robot;

import com.xxmw.transaction.common.entity.R;
import com.xxmw.transaction.common.excep.service.TransactionException;
import com.xxmw.transaction.enumeration.BitforexSymbolEnum;
import com.xxmw.transaction.enumeration.HuobiSymbolEnum;
import com.xxmw.transaction.model.robot.RobotStrategy;
import com.xxmw.transaction.service.robot.RobotStrategyService;
import com.xxmw.transaction.valid.DecimalGt;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;

/**
 * 机器人策略配置
 * @author luowenliang
 * @since 2020/2/23 14:05
 */
@Validated
@RestController
@RequestMapping("/admin/robot/strategy")
public class RobotStrategyController {

    @Autowired
    private RobotStrategyService robotStrategyService;

    /**
     * 策略获取
     * @return
     */
    @GetMapping("/list")
    @RequiresPermissions("robot:strategy:list")
    public R list () {
        return R.ok(robotStrategyService.list());
    }

    /**
     * 策略添加
     * @return
     */
    @PostMapping("/save")
    @RequiresPermissions("robot:strategy:save")
    public R save (@NotNull(message = "请选择交易所") @RequestParam(value = "bourse") Integer bourse,
                   @NotBlank(message = "交易对不能为空") @RequestParam(value = "symbol") String symbol,
                   @DecimalGt(value = "0", message = "阈值必须大于0") @RequestParam(value = "threshold") String threshold,
                   @DecimalGt(value = "0", message = "挂单最小数量必须大于0") @RequestParam(value = "minNum") String minNum,
                   @DecimalGt(value = "0", message = "日成交量必须大于0")  @RequestParam(value = "dayVolume") String dayVolume,
                   @Min(value = 1, message = "单笔订单数必须大于0") @Max(value = 5, message = "单笔订单数不能超过5") @RequestParam(value = "orderNum") Integer orderNum) {

        if (null != robotStrategyService.getByBourseAndSymbol(bourse, symbol)) {
            return R.error("已有该币种策略，请勿重复添加");
        }
        this.orderNumCheck(bourse, symbol, minNum, dayVolume);
        RobotStrategy strategy = new RobotStrategy();
        strategy.setSymbol(symbol);
        strategy.setThreshold(new BigDecimal(threshold));
        strategy.setMinNum(new BigDecimal(minNum));
        strategy.setBourse(bourse);
        strategy.setOrderNum(orderNum);

        strategy.setDayVolume(new BigDecimal(dayVolume));
        strategy.setMinuteVolume(strategy.getDayVolume().divide(new BigDecimal("1440"), 8, BigDecimal.ROUND_HALF_UP));
        robotStrategyService.save(strategy);
        return R.ok();
    }

    /**
     * 策略修改
     * @return
     */
    @PostMapping("/update")
    @RequiresPermissions("robot:strategy:update")
    public R update (@RequestParam(value = "id") Integer id,
                     @DecimalGt(value = "0", message = "阈值必须大于0") @RequestParam(value = "threshold") String threshold,
                     @DecimalGt(value = "0", message = "挂单最小数量必须大于0") @RequestParam(value = "minNum") String minNum,
                     @DecimalGt(value = "0", message = "日成交量必须大于0")  @RequestParam(value = "dayVolume") String dayVolume,
                     @Min(value = 1, message = "单笔订单数必须大于0") @Max(value = 5, message = "单笔订单数不能超过5") @RequestParam(value = "orderNum") Integer orderNum) {
        RobotStrategy strategy = robotStrategyService.getById(id);
        if (null == strategy) {
            return R.error("该策略不存在");
        }
        this.orderNumCheck(strategy.getBourse(), strategy.getSymbol(), minNum, dayVolume);
        strategy.setThreshold(new BigDecimal(threshold));
        strategy.setMinNum(new BigDecimal(minNum));
        strategy.setOrderNum(orderNum);
        strategy.setDayVolume(new BigDecimal(dayVolume));
        strategy.setMinuteVolume(strategy.getDayVolume().divide(new BigDecimal("1440"), 8, BigDecimal.ROUND_HALF_UP));
        robotStrategyService.updateById(strategy);
        return R.ok();
    }

    private void orderNumCheck (Integer bourse, String symbol, String minNum, String dayVolume) {

        String minOrderNum = null;
        switch (bourse) {
            case 1:
                minOrderNum = HuobiSymbolEnum.getBySymbol(symbol).getMinOrderNum();
                break;
            case 2:
                //TODO 币安
                minOrderNum = "0";
                break;
            case 3:
                //TODO OKEX
                minOrderNum = "0";
                break;
            case 4:
                //TODO 币夫
                minOrderNum = BitforexSymbolEnum.getBySymbol(symbol).getMinOrderNum();
                break;
            default:
                throw new TransactionException("未知的交易所");
        }

        if (new BigDecimal(minOrderNum).compareTo(new BigDecimal(minNum)) == 1) {
            throw new TransactionException("该交易该币种最小挂单数量为" + minOrderNum);
        }
    }
}
